package insight.google.game.era.core.hub;

import java.io.Serializable;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;

import javax.jdo.annotations.FetchGroup;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.repackaged.com.google.io.protocol.proto.ProtocolDescriptor.EnumType;

import insight.google.game.era.bo.GameActionLog;
import insight.google.game.era.bo.GameRoom;
import insight.google.game.era.bo.GameUser;
import insight.google.game.era.bo.Message;
import insight.google.game.era.bo.card.CharacterCard;
import insight.google.game.era.bo.card.GameCard;
import insight.google.game.era.bo.card.RoleCard;
import insight.google.game.era.client.proxy.ChatClientProxyImpl;
import insight.google.game.era.client.proxy.HostClientProxyImpl;
import insight.google.game.era.client.proxy.PlayerClientProxyImpl;
import insight.google.game.era.client.proxy.RoomClientProxyImpl;
import insight.google.game.era.core.Util;

import insight.google.game.era.service.HostServiceCenterImpl;

@PersistenceCapable(identityType = IdentityType.APPLICATION)
@FetchGroup(name = "eventList", members = { @Persistent(name = "pendingUser")})
public class PendingEvents{

	private static final Log log = LogFactory.getLog(GameRoom.class);
	
	
    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Key eventId;

	@Persistent
	private String functionName;

	@Persistent
	private String jsComponentId;

	//@Persistent
	private Object data;
	
	@Persistent
	private PendingEventInfo info;

	@Persistent(mappedBy ="eventList")
	private GameUser pendingUser;

	@Persistent
	private String sendUserId;
	
	@Persistent
	private String targetUserId;
	
	@Persistent
	private String roomId;
	
	@Persistent
	private String cardId;
	
	@Persistent
	private String cardName;
	
	@Persistent
	private String callbackFunctionName;
	
	@Persistent
	private String paramStr1;
	
	@Persistent
	private String paramStr2;
	
	@Persistent
	private String paramStr3;
	
	@Persistent
	private List<String> paramList1;
	
	@Persistent
	private List<String> paramList2;
	
	@Persistent
	private List<String> paramList3;

	public String getSendUserId() {
		return sendUserId;
	}

	public void setSendUserId(String sendUserId) {
		this.sendUserId = sendUserId;
	}

	public String getTargetUserId() {
		return targetUserId;
	}

	public void setTargetUserId(String targetUserId) {
		this.targetUserId = targetUserId;
	}

	public String getRoomId() {
		return roomId;
	}

	public void setRoomId(String roomId) {
		this.roomId = roomId;
	}

	public String getCardId() {
		return cardId;
	}

	public void setCardId(String cardId) {
		this.cardId = cardId;
	}

	public String getCallbackFunctionName() {
		return callbackFunctionName;
	}

	public void setCallbackFunctionName(String callbackFunctionName) {
		this.callbackFunctionName = callbackFunctionName;
	}

	public String getParamStr1() {
		return paramStr1;
	}

	public void setParamStr1(String paramStr1) {
		this.paramStr1 = paramStr1;
	}

	public String getParamStr2() {
		return paramStr2;
	}

	public void setParamStr2(String paramStr2) {
		this.paramStr2 = paramStr2;
	}

	public String getParamStr3() {
		return paramStr3;
	}

	public void setParamStr3(String paramStr3) {
		this.paramStr3 = paramStr3;
	}

	public List<String> getParamList1() {
		return paramList1;
	}

	public void setParamList1(List<String> paramList1) {
		this.paramList1 = paramList1;
	}

	public List<String> getParamList2() {
		return paramList2;
	}

	public void setParamList2(List<String> paramList2) {
		this.paramList2 = paramList2;
	}

	public List<String> getParamList3() {
		return paramList3;
	}

	public void setParamList3(List<String> paramList3) {
		this.paramList3 = paramList3;
	}

	public String getFunctionName() {
		return functionName;
	}
	public void setFunctionName(String functionName) {
		this.functionName = functionName;
	}
	public String getJsComponentId() {
		return jsComponentId;
	}
	public void setJsComponentId(String jsComponentId) {
		this.jsComponentId = jsComponentId;
	}
	public Object getData() {
		return data;
	}
	public void setData(Object data) {
		this.data = data;
	}
	

	
	public boolean processPendingEvents( GameUser user){
		log.debug("PendingEvents.processPendingEvents() --  user : "+ user.getName());
		log.debug("PendingEvents.processPendingEvents() --  user script proxy : "+ user.getScriptProxy());
		log.debug("PendingEvents.processPendingEvents() --  functionName : "+ this.functionName);
		log.debug("PendingEvents.processPendingEvents() --  data : "+ this.data);
		switch (UserEvents.getEventByValue(functionName)) {
//		case HOSTPROXY_SHOWMAINPAGE:
//			HostClientProxyImpl.getInstance().showMainPage(user.getScriptProxy(), jsComponentId, data);
//			break;
//		case ROOMPROXY_NOTIFYUSERJOINED:
//			HashMap<String, Object> tmpData=((HashMap<String, Object>)data);
//			GameUser dataUser = (GameUser)tmpData.get("user");
//			long dataVersion = (Long)tmpData.get("version");
//			log.debug("PendingEvents.processPendingEvents() --  dataUser : "+ dataUser.getName());
//			RoomClientProxyImpl.getInstance().notifyUserJoined(user.getScriptProxy(), this.jsComponentId, dataUser, dataVersion);
//			break;
//		case ROOMPROXY_GAMELOGACTION:
//			RoomClientProxyImpl.getInstance().updateGameLog(user.getScriptProxy(), this.getJsComponentId(),(List<GameActionLog>) this.data);
//			break;
//		case ROOMPROXY_GAME_RESULT:
//			RoomClientProxyImpl.getInstance().showGameResult(user.getScriptProxy(), this.getJsComponentId(),(List<GameUser>) this.data);
//			break;	
//		case ROOMPROXY_READYFORSTART:
//			RoomClientProxyImpl.getInstance().setReadyForStart(user.getScriptProxy(), this.jsComponentId);
//			break;
//		case ROOMPROXY_ROOMINIT:
//			
//			
//			break;
//		case ROOMPROXY_PUBLICDATAVERSION:
//			RoomClientProxyImpl.getInstance().publicDataVersion(user.getScriptProxy(), this.jsComponentId, (Long)this.data);
//			break;
//		case ROOMPROXY_SHOW_ERROR_MSG:
//			RoomClientProxyImpl.getInstance().errorMsgShow(user.getScriptProxy(), this.jsComponentId, (String)data);
//			break;
//		case ROOMPROXY_NOTIFY_ACTIVE_USER:
//			log.debug("PendingEvents.processPendingEvents() --  dataUser : "+ ((GameUser)data).getName());
//			RoomClientProxyImpl.getInstance().notifyActiveUser(user.getScriptProxy(), this.jsComponentId, (GameUser)data);
//			break;
//		case ROOMPROXY_NOTIFY_USER_LIFE_COUNT:
//			RoomClientProxyImpl.getInstance().notifyUserLifeCount(user.getScriptProxy(), this.jsComponentId, (GameUser)((List)data).get(0),(Integer)((List)data).get(1),(Boolean)((List)data).get(2));
//			break;
//		case ROOMPROXY_NOTIFY_USER_CARD_COUNT:
//			RoomClientProxyImpl.getInstance().notifyUserCardCount(user.getScriptProxy(), this.jsComponentId,(HashMap<String, String>)data);
//			break;
//		case ROOMPROXY_NOTIFY_USER_EQUIPEMENT_CARD:
//			RoomClientProxyImpl.getInstance().notifyUserEquipementCard(user.getScriptProxy(), this.jsComponentId, (HashMap<String, Collection<GameCard>>)data);
//			break;
//		case ROOMPROXY_NOTIFY_USER_PLAYED_CRAD:
//			RoomClientProxyImpl.getInstance().notifyUserPlayedCard(user.getScriptProxy(), this.jsComponentId, (HashMap<String, GameCard>)this.data);
//			break;
//		case ROOMPROXY_SHOW_USER_LIST:
//			RoomClientProxyImpl.getInstance().showRoomUsers(user.getScriptProxy(), this.jsComponentId, (Collection<GameUser>) this.data);
//			break;	
//		case PLAYERPROXY_DISPATCH_ROLECARDS:
//			log.debug("User role card --   "+(RoleCard)((HashMap<String, Object>)this.data).get("roleCard"));
//			PlayerClientProxyImpl.getInstance().dispatchRoleCard(
//					user.getScriptProxy(), this.jsComponentId,
//					(RoleCard)((HashMap<String, Object>)this.data).get("roleCard"), (Long)((HashMap<String, Object>)this.data).get("version"));
//			break;
//		case PLAYERPROXY_DISPATCH_CHARACTERCARDS:
//			log.debug("User character card --   "+(CharacterCard)((HashMap<String, Object>)this.data).get("characterCard"));
//			PlayerClientProxyImpl.getInstance().dispatchCharacterCard(
//					user.getScriptProxy(), this.jsComponentId,
//					(CharacterCard)((HashMap<String, Object>)this.data).get("characterCard"), (Long)((HashMap<String, Object>)this.data).get("version"));
//			break;	
//		case PLAYERPROXY_SHOW_ROLECARDS:
////			PlayerClientProxyImpl.getInstance().showRoleCard(user.getScriptProxy(), this.jsComponentId, (String)this.data);
//			break;	
//		case PLAYERPROXY_SHOW_CHARACTERCARDS:
//			PlayerClientProxyImpl.getInstance().showCharacterCardToUser(user.getScriptProxy(), this.jsComponentId, (GameUser)this.data);
//			break;	
		case PLAYERPROXY_DISPATCH_CARDS:
			List<String> gameCardIdList = this.getParamList1();
			PlayerClientProxyImpl.getInstance().dispatchCard(user.getScriptProxy(), this.jsComponentId, 
					Util.converStringToGameCardList(gameCardIdList));
			break;	
//		case PLAYERPROXY_RECIEVE_CARDS:
//			PlayerClientProxyImpl.getInstance().recieveCard(user.getScriptProxy(), this.jsComponentId, (List<GameCard>)this.data);
//			break;	
		case PLAYERPROXY_ATACKCARD_POLICYEXECUTE:
			PlayerClientProxyImpl.getInstance().attackCardPolicyExe(user.getScriptProxy(), 
					this.jsComponentId,
					this.callbackFunctionName,
					this.sendUserId,
					this.getCardName());
			break;
			
		case PLAYERPROXY_DUALCARD_POLICYEXECUTE:
			PlayerClientProxyImpl.getInstance().duelCardPolicyExe(user.getScriptProxy(), 
					this.jsComponentId,
					((HashMap<String, String>)data).get("card"),
					((HashMap<String, String>)data).get("methodName"),
					((HashMap<String, String>)data).get("senderName"));
			break;	
//		case PLAYERPROXY_MILKCARD_POLICYEXECUTE:
//			PlayerClientProxyImpl.getInstance().milkCardPolicyExe(user.getScriptProxy(),
//					this.jsComponentId, 
//					((HashMap<String, String>)data).get("methodName"),
//					Integer.valueOf(((HashMap<String, String>)data).get("lifeCount")));
//			break;	
//		case PLAYERPROXY_SETACTIVE:
//			PlayerClientProxyImpl.getInstance().setActive(user.getScriptProxy(), this.jsComponentId, (Boolean)data);
//			break;	
//		case PLAYERPROXY_HEAL_LIFE:
//			PlayerClientProxyImpl.getInstance().healLife(user.getScriptProxy(), this.jsComponentId,(Integer)this.data);
//			break;	
//		case PLAYERPROXY_RECIEVE_PLAYERCARD:
//			PlayerClientProxyImpl.getInstance().recievePlayerCard(
//					user.getScriptProxy(), this.jsComponentId, (List<GameCard>)data);
//			break;	
//		case PLAYERPROXY_DISPLAY_LIFECOUNT:
//
//			break;	
		case PLAYERPROXY_SETACTIVECARD:
			PlayerClientProxyImpl.getInstance().setActiveCard(user.getScriptProxy(), this.jsComponentId,this.paramList1);
			break;	
		case PLAYERPROXY_ENABLE_POLICYEXECUTE:
			PlayerClientProxyImpl.getInstance().enablePolicyExec(user.getScriptProxy(), this.jsComponentId,(GameUser)data);
			break;	
		case PLAYERPROXY_REGISTER_ATTACKABLEUSER:
			List<String> userList = this.getParamList1();
			PlayerClientProxyImpl.getInstance().registerAttackableUser(user.getScriptProxy(), 
					this.jsComponentId, Util.converStringToGameUserList(userList));
			break;	
//		case PLAYERPROXY_SELECT_DROPCARDS:
//			PlayerClientProxyImpl.getInstance().selectDropCard(user.getScriptProxy(), this.jsComponentId,(Integer)this.data);
//			break;	
//		case PLAYERPROXY_FINISH_DROPCARDS:
//			PlayerClientProxyImpl.getInstance().finishDropCard(user.getScriptProxy(), this.jsComponentId);
//			break;	
//		case PLAYERPROXY_FINISH_POLICYEXECUTE:
//
//			break;	
		case PLAYERPROXY_REMOVE_CLIENT_SELECTEDCARD:
			PlayerClientProxyImpl.getInstance().removeClientSelectedCard(user.getScriptProxy(), this.jsComponentId);
			break;	
		case PLAYERPROXY_REPLACE_EQUIPEMENTCARD:
			PlayerClientProxyImpl.getInstance().replaceEquipmentCard(user.getScriptProxy(), this.jsComponentId,(GameCard)this.data);
			break;	
		case PLAYERPROXY_REMOVE_CLIENT_CARD:
			PlayerClientProxyImpl.getInstance().removeClientCard(user.getScriptProxy(), this.jsComponentId);
			break;	
//		case PLAYERPROXY_SHOW_CARD_TO_USER:
//
//			break;	
//		case PLAYERPROXY_UPDATE_UI_PROFILE:
//
//			break;	
//		case PLAYERPROXY_PROFILE_CHANGE_NOTIFICATION:
//
//			break;	
//		case PLAYERPROXY_READY_TO_PLAY:
//			PlayerClientProxyImpl.getInstance().readyToPlay(user.getScriptProxy(), this.jsComponentId);
//			break;	
//		case CHATPROXY_SENDMSG:
//			ChatClientProxyImpl.getInstance().showChatMessage(user.getScriptProxy(), this.jsComponentId,(Message) this.data);
//			break;	
//		case PLAYERPROXY_ASK_CARD_DISCARD:
//			PlayerClientProxyImpl.getInstance().askCardDiscardExec(user.getScriptProxy(), 
//					this.jsComponentId,
//					((HashMap<String, String>)data).get("card"),
//					((HashMap<String, String>)data).get("methodName"),
//					((HashMap<String, String>)data).get("senderName"));
//			break;	
//		case ROOMPROXY_ROOMINIT:
//
//			break;	
			
		default:
			break;
		}
		
		return true;
	}
	public GameUser getPendingUser() {
		return pendingUser;
	}
	public void setPendingUser(GameUser pendingUser) {
		this.pendingUser = pendingUser;
	}
	public Key getEventId() {
		return eventId;
	}
	public void setEventId(Key eventId) {
		this.eventId = eventId;
	}
	
	public String toString() {
		return KeyFactory.keyToString(eventId);
	}
	
	public PendingEventInfo getInfo() {
		return info;
	}
	public void setInfo(PendingEventInfo info) {
		this.info = info;
	}

	public String getCardName() {
		return cardName;
	}

	public void setCardName(String cardName) {
		this.cardName = cardName;
	}
}
